package org.lilred.nzbberry.controllers;

import java.util.Vector;

import net.rim.device.api.ui.MenuItem;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.Dialog;
import net.rim.device.api.ui.component.Menu;

import org.json.me.JSONArray;
import org.json.me.JSONException;
import org.json.me.JSONObject;
import org.lilred.nzbberry.models.HistoryModel;
import org.lilred.nzbberry.models.HistoryNzbModel;
import org.lilred.nzbberry.observer.Observable;
import org.lilred.nzbberry.observer.Observer;
import org.lilred.nzbberry.views.AppView;
import org.lilred.nzbberry.views.PageView;
import org.lilred.nzbberry.webservice.RequestsOutput;
import org.lilred.nzbberry.webservice.SabnzbdActionClient;
import org.lilred.nzbberry.webservice.SabnzbdOutputClient;

public class HistoryController extends PageController implements Observable, RequestsOutput {
	private Vector observers = new Vector();
	private HistoryModel model = new HistoryModel();
	public HistoryController() { 
		view = new PageView() {
			protected void onVisibilityChange(boolean visible) {
				if (visible) refresh();
			}
		};
	}

	public void refresh() {
		for (int i = 0; i < observers.size(); i++) {
			((Observer) observers.elementAt(i)).updateObserver(this, AppController.STARTED);
		}
		SabnzbdOutputClient historyClient = new SabnzbdOutputClient("history", this);
		historyClient.start();
	}

	public void registerObserver(Observer o) {
		observers.addElement(o);
	}

	public void webserviceOutputReceived(JSONObject jobj) {
		try {
			jobj = jobj.getJSONObject("history");
			JSONArray slots = jobj.getJSONArray("slots");
			AppView.getInstance().appManager.historyButton.setBadges(slots.length());
			for (int i = 0; i < slots.length(); i++) {
				HistoryNzbModel m = new HistoryNzbModel(i, slots.getJSONObject(i));
				if (model.size() <= i) {
					final HistorySlotController sc = new HistorySlotController(this, m); 
					model.addSlot(sc);
					UiApplication.getUiApplication().invokeLater(new Runnable() {
						public void run() {
							view.add(sc.view);
						}
					});
				} else {
					//Otherwise, we just need to update the slot
					model.getSlot(i).setModel(m); 
				}			
			}
			//Delete any extra slots that remain from downloads that completed or downloads that were deleted remotely
			for (int i = slots.length(); i < model.size(); i++) {
				final HistorySlotController c = model.getSlot(i);
				model.deleteSlot(c);
				UiApplication.getUiApplication().invokeLater(new Runnable() {
					public void run() {	
						try {
							view.delete(c.view);
						} catch (Exception e){
							System.out.println(e.getMessage());
						}
					}
				});
			}
			for (int i = 0; i < observers.size(); i++) {
				((Observer) observers.elementAt(i)).updateObserver(this, AppController.COMPLETED);
			}
		} catch (JSONException e) {
			for (int i = 0; i < observers.size(); i++) {
				((Observer) observers.elementAt(i)).updateObserver(this, AppController.ERROR);
			}
		}
	}

	public void webserviceRequestFailed() {
		for (int i = 0; i < observers.size(); i++) {
			((Observer) observers.elementAt(i)).updateObserver(this, AppController.ERROR);
		}
	}

	public void delete(HistorySlotController historySlotController) {
		model.deleteSlot(historySlotController);
		view.delete(historySlotController.view);
	}

	public Menu makeMenu(Menu menu) {
		menu.add(refreshHistoryMenuItem);
		menu.add(clearHistoryMenuItem);
		return menu;
	}

	public MenuItem refreshHistoryMenuItem = new MenuItem("Refresh History", 10, 10) {
		public void run() { refresh(); }
	};

	public MenuItem clearHistoryMenuItem = new MenuItem("Delete History", 20, 20) {
		public void run() { deleteHistory(); }
	};

	public void deleteHistory() {
		int result = Dialog.ask(Dialog.D_YES_NO, "Are you sure you want to delete the entire history?");
		if (result == Dialog.YES) {
			SabnzbdActionClient deleteHistoryClient = new SabnzbdActionClient();
			deleteHistoryClient.deleteHistory();
			for (int i = 0; i < model.size(); i++) {
				model.deleteSlot(model.getSlot(i));
			}
		}
	}
}
